package GUI.pdaGrafica;

import javax.swing.JPanel;
import javax.swing.JWindow;
import java.awt.Dimension;
import java.awt.Rectangle;
import javax.swing.BorderFactory;
import javax.swing.border.EtchedBorder;
import javax.swing.border.TitledBorder;
import java.awt.Font;
import java.awt.Color;
import javax.swing.JList;
import javax.swing.JScrollPane;
import javax.swing.border.BevelBorder;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.DefaultListModel;
import javax.swing.JOptionPane;
import javax.swing.JSpinner;
import javax.swing.JLabel;
import javax.swing.JButton;
import javax.swing.ImageIcon;
import javax.swing.ListSelectionModel;
import javax.swing.SpinnerNumberModel;

import modelo.Restaurante;
import modelo.gestionPedidos.Pedido;
import modelo.gestionReserva.Mesa;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.Point;
import java.util.LinkedList;
import java.util.List;
import java.util.ListIterator;
/**
 * Esta clase implementa la sección para crear/ampliar pedidos
 * 
 * @created 03-may-2007 23:11
 * @version 1.0
 * @author Enrique Menor Santos
 *
 */
public class CrearAmpliarPedido extends JWindow implements ActionListener, ListSelectionListener, ChangeListener{

	private static final long serialVersionUID = 1L;

	private JPanel jContentPane = null;

	private JScrollPane jSPMesasDisponibles = null;
	
	private JSpinner jSpNumComensales = null;

	private JLabel jLComensales = null;

	private JButton jBAceptar = null;

	private JButton jBCancelar = null;

	/**
	 * Objeto restaurante a gestionar. Se pasará como parámetro al resto de clases visuales. 
	 */
	private Restaurante r;
	/**
	 * Almacena el pedido a ampliar en caso que se haya llamado a Ampliar Pedido
	 */
	private Pedido pedidoAmpliar=null;
	/**
	 * Lista que será la vista de la lista de mesas libres del Restaurante
	 */
	private JList jLMesasLibres = null;
	/**
	 * El modelo de la vista anterior. Contendrá las mesas libres del Restaurante
	 */
	private DefaultListModel listaModelo;
	/**
	 * Lista de Mesas libres que obtenemos del objeto restaurante
	 * @param r
	 */
	private List<Mesa> listaMesasLibres;
	
	
	/**
	 * Constructor con un sólo parámetro. 
	 * Será llamado cuando se vaya a crear un nuevo Pedido.
	 * @param r
	 */
	public CrearAmpliarPedido(Restaurante r) {
		this.r=r;
		this.pedidoAmpliar=null;
		//obtenemos la lista de mesas libres directamente de la BD a través del objeto restaurante
		this.listaMesasLibres = r.obtenerMesasLibres(r.getId());
		if(listaMesasLibres == null)
			System.err.println("ERROR al recuperar de la BD la lista de mesas libres desde la GUI CREAR PEDIDO");
		initialize();
	}
	/**
	 * Constructor con un sólo parámetro. 
	 * Será llamado cuando se vaya a ampliar un Pedido existente.
	 * @param r
	 * @param pedidoSeleccionado
	 */
	public CrearAmpliarPedido(Restaurante r, Pedido pedidoSeleccionado) {
		this.r=r;
		this.pedidoAmpliar=pedidoSeleccionado;
		//obtenemos la lista de mesas libres directamente de la BD a través del objeto restaurante
		this.listaMesasLibres = r.obtenerMesasLibres(r.getId());
		if(listaMesasLibres == null)
			System.err.println("ERROR al recuperar de la BD la lista de mesas libres desde la GUI AMPLIAR PEDIDO");
		initialize();
	}

	/**
	 * This method initializes this
	 * 
	 * @return void
	 */
	private void initialize() {
		this.setMaximumSize(new Dimension(240, 320));
		this.setName("crearAmpliarPedido");
		this.setBounds(new Rectangle(0, 0, 240, 320));
		this.setMinimumSize(new Dimension(240, 320));
		this.setPreferredSize(new Dimension(240, 320));
		this.setContentPane(getJContentPane());
	}

	/**
	 * This method initializes jContentPane
	 * 
	 * @return javax.swing.JPanel
	 */
	private JPanel getJContentPane() {
		if (jContentPane == null) {
			jLComensales = new JLabel();
			jLComensales.setText("Comensales:");
			jLComensales.setSize(new Dimension(100, 25));
			jLComensales.setIcon(new ImageIcon(getClass().getResource("/iconos/user.png")));
			jLComensales.setLocation(new Point(16, 231));
			jContentPane = new JPanel();
			jContentPane.setLayout(null);
			if (this.pedidoAmpliar==null)
				jContentPane.setBorder(BorderFactory.createTitledBorder(BorderFactory.createEtchedBorder(EtchedBorder.LOWERED), "CREAR PEDIDO", TitledBorder.CENTER, TitledBorder.ABOVE_TOP, new Font("Dialog", Font.BOLD, 12), new Color(51, 51, 51)));
			else
				jContentPane.setBorder(BorderFactory.createTitledBorder(BorderFactory.createEtchedBorder(EtchedBorder.LOWERED), "AMPLIAR PEDIDO", TitledBorder.CENTER, TitledBorder.ABOVE_TOP, new Font("Dialog", Font.BOLD, 12), new Color(51, 51, 51)));
			jContentPane.setToolTipText("Seleccione las mesas que compondrán el pedido y el número de comensales");
			jContentPane.setName("panelCrearAmpliarPedidos");
			jContentPane.add(getJSPMesasDisponibles(), null);
			jContentPane.add(getJSpNumComensales(), null);
			jContentPane.add(jLComensales, null);
			jContentPane.add(getJBAceptar(), null);
			jContentPane.add(getJBCancelar(), null);
		}
		return jContentPane;
	}

	/**
	 * This method initializes jSPMesasDisponibles	
	 * 	
	 * @return javax.swing.JScrollPane	
	 */
	private JScrollPane getJSPMesasDisponibles() {
		if (jSPMesasDisponibles == null) {
			jSPMesasDisponibles = new JScrollPane();
			jSPMesasDisponibles.setBounds(new Rectangle(5, 28, 231, 198));
			jSPMesasDisponibles.setToolTipText("Mesas disponibles en el momento actual");
			jSPMesasDisponibles.setViewportView(getJLMesasLibres());
			jSPMesasDisponibles.setBorder(BorderFactory.createTitledBorder(BorderFactory.createBevelBorder(BevelBorder.LOWERED), "Mesas disponibles:", TitledBorder.LEFT, TitledBorder.ABOVE_TOP, new Font("Dialog", Font.BOLD, 12), new Color(51, 51, 51)));
		}
		return jSPMesasDisponibles;
	}

	/**
	 * This method initializes jLMesasLibres	
	 * 	
	 * @return javax.swing.JList	
	 */
	private JList getJLMesasLibres() {
		if (jLMesasLibres == null) {
			
			//nos creamos la lista modelo
			this.listaModelo  = new DefaultListModel();
			//si hemos importado la lista de mesas libres correctamente, añadimos las mesas a la lista del modelo
			if(listaMesasLibres != null)
			{
				//recorremos la lista de mesas libres y vamos insertando sus numeros de masa
				ListIterator<Mesa> it= listaMesasLibres.listIterator();
				while(it.hasNext())
				{
					Mesa m = it.next();
					listaModelo.addElement("Mesa "+m.getNumMesa());					
				}
			}
			jLMesasLibres = new JList(listaModelo);
			jLMesasLibres.setModel(listaModelo);
			jLMesasLibres.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);		
			jLMesasLibres.addListSelectionListener(this);
			
		}
		return jLMesasLibres;
	}

	/**
	 * This method initializes jSpNumComensales	
	 * 	
	 * @return javax.swing.JSpinner	
	 */
	private JSpinner getJSpNumComensales() {
		if (jSpNumComensales == null) {
			//primero me creo un modelo numerico de spinner:
			//valor inicial=1
			//valor minimo=1
			//valor maximo=99
			//incremento=1		
			int valorInicial=1;
			if (this.pedidoAmpliar!=null)
				valorInicial=pedidoAmpliar.getNumComensales();
			SpinnerNumberModel model = new SpinnerNumberModel(valorInicial,1,99,1);
			jSpNumComensales = new JSpinner(model);
			jSpNumComensales.setLocation(new Point(120, 232));
			jSpNumComensales.setSize(new Dimension(90, 25));
			jSpNumComensales.addChangeListener(this);
		}
		return jSpNumComensales;
	}

	/**
	 * This method initializes jBAceptar	
	 * 	
	 * @return javax.swing.JButton	
	 */
	private JButton getJBAceptar() {
		if (jBAceptar == null) {
			jBAceptar = new JButton();
			jBAceptar.setMnemonic(KeyEvent.VK_ACCEPT);
			jBAceptar.setText("Aceptar");
			jBAceptar.setToolTipText("Se creará un nuevo pedido en el sistema");
			jBAceptar.setLocation(new Point(6, 270));
			jBAceptar.setSize(new Dimension(110, 30));
			jBAceptar.setEnabled(false);
			jBAceptar.setIcon(new ImageIcon(getClass().getResource("/iconos/accept.png")));
			jBAceptar.addActionListener(this);
		}
		return jBAceptar;
	}

	/**
	 * This method initializes jBCancelar	
	 * 	
	 * @return javax.swing.JButton	
	 */
	private JButton getJBCancelar() {
		if (jBCancelar == null) {
			jBCancelar = new JButton();
			jBCancelar.setIcon(new ImageIcon(getClass().getResource("/iconos/cancel.png")));
			jBCancelar.setMnemonic(KeyEvent.VK_CANCEL);
			jBCancelar.setLocation(new Point(124, 270));
			jBCancelar.setSize(new Dimension(110, 30));
			jBCancelar.setText("Cancelar");
			jBCancelar.addActionListener(this);
		}
		return jBCancelar;
	}
	/**
	 * TODO:Gestion de los botones
	 */
	public void actionPerformed(ActionEvent e) {
		
		if (e.getActionCommand().equals("Cancelar"))
		{
			this.dispose();	//esconde la ventana y se deshace de ella
			new Pedidos(r).setVisible(true);			
		}
		else if (e.getActionCommand().equals("Aceptar"))
		{
			//recogemos un array con los indices de las mesas seleccionadas 
			int[] indices = this.getJLMesasLibres().getSelectedIndices();
			int n = ((Number)(this.getJSpNumComensales().getValue())).intValue();
			List<Mesa> mesasPedido = new LinkedList<Mesa>();		//mesas que van a componer el pedido
			if (indices.length>0)
			{								
				for (int i=0;i<indices.length;i++)
					mesasPedido.add(this.listaMesasLibres.get(indices[i]));
			}
			//	Finalmente,
			if(this.pedidoAmpliar==null &&	!r.anadirPedido(mesasPedido, n))//añadimos el pedido al restaurante
					JOptionPane.showMessageDialog(
							this,
							"No se ha podido añadirse el pedido",
							"ERROR al añadir el pedido",
							JOptionPane.ERROR_MESSAGE);
			
			else if(this.pedidoAmpliar!=null && !r.ampliarPedido(this.pedidoAmpliar, mesasPedido, n))				
				JOptionPane.showMessageDialog(
							this,
							"No se ha podido ampliar el pedido",
							"ERROR al ampliar el pedido",
							JOptionPane.ERROR_MESSAGE);
		
			this.dispose();	//esconde la ventana y se deshace de ella
			new Pedidos(r).setVisible(true);
		}
		
	}
	/**
	 * TODO:Gestion de los valores cambiados de la lista.
	 * Este método se ejecuta cuando se ha producido un cambio en la lista .
	 * Si estamos en Crear Pedido, Aceptar debe estarhabilitado si hay al menos una mesa seleccionada.
	 * Si estamos en Ampliar Pedido, el boton Aceptar se pone enabled
	 */
	public void valueChanged(ListSelectionEvent e) 
	{
		//CrearPedido
		if(pedidoAmpliar==null)
		{
			//no hay ningún elemento seleccionado
			if( ((JList)(e.getSource())).isSelectionEmpty())
				this.getJBAceptar().setEnabled(false);
			//hay al menos un elemento seleccionado
			else
				this.getJBAceptar().setEnabled(true);
		}
		else 	//AmpliarPedido
		{
			int valor = ((Number)(this.getJSpNumComensales().getValue())).intValue();
			//no hay ningún elemento seleccionado y el valor del spinner es el mismo
			if( ((JList)(e.getSource())).isSelectionEmpty() && pedidoAmpliar.getNumComensales()==valor)
				this.getJBAceptar().setEnabled(false);
			//hay al menos un elemento seleccionado
			else
				this.getJBAceptar().setEnabled(true);
			
		}
		
	}
	/**
	 * Gestion de eventos de cambio en el spinner.
	 * Si estamos en Crear Pedido no pasa nada.
	 * Si estamos en Ampliar Pedido, el boton Aceptar se pone enabled
	 * @param e
	 */
	public void stateChanged(ChangeEvent e) 
	{
		int valor = ((Number)(this.getJSpNumComensales().getValue())).intValue();
		//AmpliarPedido: el valor del spinner tiene que ser distinto al que ya había
		if (pedidoAmpliar!=null)
		{
			if(pedidoAmpliar.getNumComensales()!=valor)
				this.getJBAceptar().setEnabled(true);	//han cambiado el num comensales
			else if(pedidoAmpliar.getNumComensales()==valor && !this.getJLMesasLibres().isSelectionEmpty())
				this.getJBAceptar().setEnabled(true);	//han cambiado el num comensales y aunque sea igual que antes, como hay mesas seleccionadas se permite ampliar
			else if(pedidoAmpliar.getNumComensales()==valor && this.getJLMesasLibres().isSelectionEmpty())
				this.getJBAceptar().setEnabled(false);	//han cambiado el num comensales,pero como no hay mesas seleccionadas no se puede ampliar
		}		
		//CrearPedido: el valor del spinner no habilita ni deshabilita el boton aceptar
	}
	}
